/**右键菜单***/
var defaultOpts = {
    trigger: 'mousedown',
    setPositionFn:undefined
};
var $body;
class Ctxmenu extends $B.BaseControl {
    constructor(elObj, opts) {
        super();
        this.$doc = opts.document ? opts.document : document;
        if (!$body) {
            $body =   this.$doc.body;
        }        
        $B.DomUtils.contextmenu(this.$doc, function (e) {
            return false;
        });       
        this.id = $B.getUUID();
        this.opts = $B.extendObjectFn(true, {}, defaultOpts, opts);
        let evs = {};
        this.allSubMenus = [];
        evs[this.opts.trigger] = (e) => {
            let isMouseDown = this.opts.trigger === "mousedown";
            if (isMouseDown) {
                this.hide();
                if (e.which !== 3) {
                    return true;
                }
            }
            let pos;
            if(isMouseDown){
                pos = { left: e.pageX, top: e.pageY };
            }else{
                let el = e.target;
                pos = $B.DomUtils.offset(el);
                pos.top = $B.DomUtils.outerHeight(el) + 2;
            }
            if(this.opts.setPositionFn){
                this.opts.setPositionFn(e.target,pos);
            }
            this.elObj = this.createMenus(this.id, e, pos, this.opts.buttons);
            $B.slideDown(this.elObj, 200);
        };
        $B.DomUtils.bind(elObj, evs);
    }
    _getOptById(id) {
        var opt = this._loopGetOptById(id, this.opts.buttons);
        return opt;
    }
    _loopGetOptById(id, buttons) {
        var opt, childrens = [];
        for (let i = 0; i < buttons.length; i++) {
            if (Array.isArray(buttons[i])) {
                opt = this._loopGetOptById(id, buttons[i]);
                if (opt) {
                    break;
                }
            } else {
                if (buttons[i].id === id) {
                    opt = buttons[i];
                    break;
                }
                if (buttons[i].children) {
                    for (let j = 0; j < buttons[i].children.length; j++) {
                        childrens.push(buttons[i].children[j]);
                    }
                }
            }
        }
        if (!opt && childrens.length > 0) {
            opt = this._loopGetOptById(id, childrens);
        }
        return opt;
    }
    _getElFromEv(e) {
        let el = e.target;
        while (el.tagName !== "BUTTON") {
            el = el.parentNode;
        }
        return el;
    }
    _getBtnElAdnOpt(e) {
        let el = this._getElFromEv(e);
        let id = $B.DomUtils.attribute(el, "id");
        var opt = this._getOptById(id);
        return {
            el: el,
            opt: opt
        };
    }
    getWrapEvents(){
        if(!this.wrapEvents){
            var _this = this;
            this.wrapEvents = {
                mouseenter: function (e) {
                    clearTimeout( _this.hideTimer );
                },
                mouseleave:function(e){
                    _this.hideTimer = setTimeout(()=>{
                         _this.hide();
                    },500);
                }
            };
        }
        return this.wrapEvents;
    }
    getEvents() {
        if (!this.events) {
            let _this = this;
            this.events = {
                mousedown: function (e) {
                    let res = _this._getBtnElAdnOpt(e);
                    let opt = res.opt;
                    if (opt.click) {
                        setTimeout(() => {
                            opt.click.call(res.el, opt);
                        }, 1);
                    }
                    setTimeout(()=>{
                        _this.hide();
                    },1);
                    return false;
                },
                mouseenter: function (e) {
                    let el = _this._getElFromEv(e);
                    let id = $B.DomUtils.attribute(el, "id");
                    if (_this.showIingEl) { 
                        let wid =  $B.DomUtils.attribute(_this.showIingEl, "id"); 
                        if(wid.indexOf(id) < 0 && id.indexOf(wid) < 0){
                            _this.showIingEl.style.display = "none";
                        } 
                    }                   
                    if ($B.DomUtils.attribute(el, "haschild")) {
                        let bodyWidth = $B.DomUtils.width($body);
                        let bodyHeight = $B.DomUtils.height($body);
                        let res = _this._getBtnElAdnOpt({ target: el });
                        let opt = res.opt;
                        let items = opt.children;
                        let id = $B.DomUtils.attribute(el, "id")+"_c";
                        let ofs = $B.DomUtils.offset(el);
                        ofs.left = ofs.left + 2;
                        ofs.top = ofs.top +  $B.DomUtils.outerHeight(el) / 2;
                        let pos = { top: ofs.top, left: ofs.left };
                        pos.left = pos.left + $B.DomUtils.outerWidth(el);
                        let childEl = _this.createMenus(id, e, pos, items,true);                     
                        $B.DomUtils.show(childEl);                       
                        let elWidth = $B.DomUtils.outerWidth(childEl);
                        let elHeight = $B.DomUtils.outerHeight(childEl);
                        let diff = bodyWidth - elWidth - pos.left;
                        let reset = false;
                        if (diff < 0) {
                            pos.left = ofs.left - elWidth;
                            reset = true;
                        }
                        diff = bodyHeight - elHeight - pos.top;
                        if (diff < 0) {
                            pos.top = ofs.top - elHeight;
                            reset = true;
                        }
                        if (reset) {
                            childEl.style.top = pos.top + "px";
                            childEl.style.left = pos.left + "px";
                        }
                        _this.showIingEl = childEl;
                    }
                }
            };
        }
        return this.events;
    }
    createMenus(id, e, pos, items,isChild) {
        let elObj = $B.DomUtils.children($body, "#" + id);
        if (!elObj) {
            elObj = $B.DomUtils.createEl("<div id='" + id + "' class='k_context_menu_container k_box_shadow k_box_size' style='position:absolute;padding: 6px 8px;display:none;z-index:" + $B.config.maxZindex + "'></div>");
            if(isChild){
                this.allSubMenus.push(elObj);
            }          
            let events = this.getEvents();
            for (let i = 0; i < items.length; i++) {
                let it = items[i];
                it["id"] = id + "_" + i;
                let text = it.text;
                let icon = it.iconCls;
                let btn = $B.DomUtils.createEl("<button class='k_toolbar_button_plain' id='" + it.id + "' style='white-space: nowrap; border-radius: 0px; display: block; margin: 0px 0px 3px; min-width: 100%; text-align: left;'></button>");
                if (icon) {
                    $B.DomUtils.append(btn, '<i class="fa ' + icon + '"></i>');
                }
                $B.DomUtils.append(btn, '<span style="white-space: nowrap; padding-left: 5px;">' + text + '</span>');
                if (it.children) {
                    $B.DomUtils.attribute(btn, { haschild: "1" });
                    $B.DomUtils.append(btn, '<i style="position:relative;font-size:10px;padding-right:-8px;padding-left:5px;top:0.5em;" class="fa fa-ellipsis"></i>');
                }
                $B.DomUtils.append(elObj, btn);
                $B.DomUtils.bind(btn, events);
            }
            $B.DomUtils.bind(elObj,this.getWrapEvents());
            $B.DomUtils.append($body,elObj);
        }else{//运动到底部
            $B.DomUtils.detach(elObj);
            $B.DomUtils.append($body,elObj);
        }
        $B.DomUtils.css(elObj, pos);
        return elObj;
    }
    hide(){
        if(this.elObj){
            $B.DomUtils.hide(this.elObj);
            $B.DomUtils.hide(this.allSubMenus);
        }
    }
    destroy(excuObjName) {
        if(this.elObj){
            $B.DomUtils.remove(this.elObj);
            $B.DomUtils.remove(this.allSubMenus);
            this.elObj = undefined;
            this.allSubMenus = undefined;
        }
        this.$doc = undefined;
        super.destroy(excuObjName);
    }
}
$B["Ctxmenu"] = Ctxmenu;